﻿using System;
using System.Collections.Generic;
using System.Text;

namespace AdaptiveAgents
{
    /// <summary>
    /// Generates random numbers
    /// </summary>
    public class Generator
    {
        //set a new random numbers generator working according to system Ticks
        public static Random generator = new Random((int)(System.DateTime.Now.Ticks / 10000)); //System.currentTimeMillis());

        /// <summary>
        /// Get a random double number 
        /// </summary>
        /// <returns>A random double number between 0.0 and 1.0</returns>
        public static double getNextDouble() { return (generator.NextDouble()); }

        /// <summary>
        /// Get a random integer number
        /// </summary>
        /// <param name="i">max number</param>
        /// <returns>A random number between 0 and (max number-1)</returns>
        public static int getNextInt(int i) { return (generator.Next(i)); }


        //handling Gaussian distribution
        private static double nextNextGaussian;
        private static bool haveNextNextGaussian = false;

        /// <summary>
        /// Get a random number according to Gaussian distribution
        /// </summary>
        /// <returns>A random number according to Gaussian distribution</returns>
        public static double getNextGaussian()
        {
            if (haveNextNextGaussian) //allready calculted a random number
            {
                haveNextNextGaussian = false;
                return nextNextGaussian;
            }
            else
            {
                //create 2 new random numbers and retunring the first one
                double v1, v2, s;
                do
                {
                    v1 = 2 * generator.NextDouble() - 1;   // between -1.0 and 1.0
                    v2 = 2 * generator.NextDouble() - 1;   // between -1.0 and 1.0
                    s = v1 * v1 + v2 * v2;
                } while (s >= 1 || s == 0);
                double multiplier = Math.Sqrt(-2 * Math.Log(s) / s);
                nextNextGaussian = v2 * multiplier;
                haveNextNextGaussian = true;
                return v1 * multiplier;
            }
        }



        public static List<double> GetRandomNumbers(int size, bool allUnique)
        {
            List<double> result = new List<double>();

            for (int i = 0; i < size; i++)
            {
                double temp = getNextDouble();
                if (allUnique)
                {
                    while (result.Contains(temp))
                    {
                        temp = getNextDouble();
                    }
                }
                result.Add(temp);                
            }

            return result;
        }
    }

}
